home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
MSC2BC.ARJ
/
CONVERT.TXT
< prev
next >
Wrap
Text File
|
1992-06-26
|
105KB
|
2,257 lines
Microsoft C to Borland C++
Conversion Guide
BORLAND INTERNATIONAL, INC. 1800 GREEN HILLS ROAD
P.O. BOX 660001, SCOTTS VALLEY, CA 95067-0001
Copyright 1992 by Borland International. All rights
reserved. All Borland products are trademarks or registered trademarks
of Borland International, Inc. Other brand and product names are
trademarks or registered trademarks of their respective holders.
If you're an experienced C or C++ programmer, but the Borland C++
programming environment and tools are new to you, then you should read
this section before you do anything else. We appreciate that you want
to be up and running fast with a new piece of software, and we know
that you want to spend as little time as possible reading manuals.
However, the time that you spend reading this section will probably
save you a lot of time later. Please read on.
Why Should You Use Borland C++, Anyway?
You may have become accustomed to using Microsoft C over the years. If
you were developing for the Windows environment in the past, Microsoft
C and the SDK were the only game in town. And maybe you are a little
skeptical that a newer product is superior to an old standby.
Compared to the Microsoft development environment, Borland C++ is a
real time saver from the moment you install it until you have debugged
your program. For most typical applications, a program compiled with
Borland C++ executes faster than when compiled with Microsoft C. The
Borland C++ environment provides you with more and better supporting
tools than Microsoft's, tools that are easier to use and that save you
many hours of time during your software development cycle. The time
that you save enables you to develop richer and better software
faster, and helps your company to remain competitive no matter what
its line of business may be.
Let's cover these areas in greater depth.
Installation.
There is one and only one installation program for Borland C++, and it
sets up all of the Borland C++ tools and resources in a single highly
integrated directory structure.
By contrast, you need to install several sets of software to be
productive with Microsoft software development products. If some of
your software is written in assembly language, you need to buy the
Microsoft Assembler separately, and install it on your system. If you
are writing software for Windows, first you must install Microsoft
C6.0a, then pick and choose the tools, libraries, and header files
from the Microsoft Windows SDK and decide where to install them. The
installation of the Microsoft Windows SDK is a manual process with
nothing to guide you or protect you from making a clerical error.
Once you have installed Borland C++, you will realize its built-in
productivity benefits. Rather than setting up INCLUDE and LIB
environment variables, you tell the Borland C++ Integrated Development
Environment (IDE) where your include files and libraries are, and the
IDE does all the rest.
PreCompiled Headers.
By making good use of extended memory, using precompiled headers, and
embodying other advanced compiler technology, Borland C++ compiles
programs lightning fast even when all of the code optimization options
and warning messages are enabled.
In a typical comparison of compilation speeds MAKEing a widely
distributed Windows application of moderate size, Borland C++ produced
an .EXE file in 46 seconds while the Microsoft tools did it in 146
seconds, over three times as long. The program consisted of 12 C
modules that contained 11000 source lines and 3 assembly language
modules totaling 1000 lines plus all of the required header and
include files. All possible compiler optimizations were enabled for
this comparison. The test PC was a 33MHz 80486 with 16MB of memory and
a SCSI hard disk with a 12 millisecond seek time.
Integrated Environments.
The Borland C++ IDE is quicker than PWB, which swaps to disk rather
than using expanded or extended memory. It is much quicker and easier
to edit several source files at once with the IDE.
Turbo C++ for Windows is a complete Windows-based system that allows
you to edit, compile, test and debug Windows applications while
remaining entirely within the Microsoft Windows environment. The Turbo
C++ for Windows program editor has a contemporary SpeedBar for
point-and-click action on common editing functions. Borland C++
project files are interchangeable between Turbo C++ for Windows and
the IDE, allowing you transparent use of the environment that suits
your needs at a given moment.
Debugging.
The Turbo Debugger (TD) user interface is more intuitive to use than
CodeView's, which retains many of the artifacts of its SYMDEB command-
oriented predecessor. TD has commands to search memory for
instructions or data elements, useful for debugging programs without
source code or sometimes even with the source code. TD can be loaded
resident to debug Terminate-and-Stay-Resident (TSR) programs. You can
debug a program running in one PC remotely from another PC in cases
where the run-time environment of a target program requires the
maximum amount of available memory. Remote debugging with TD is
possible via either a serial port or across a local area network
(LAN). TD has companion driver modules which enable hardware-level
debugging using the 386 debug registers.
Turbo Debugger for Windows runs inside Windows and allows you to debug
Windows programs using a system with only a single monitor. When
invoked, it saves the Windows screen context, displays debugging info,
then switches back to Windows. CodeView requires two monitors for
debugging, typically a color monitor for Windows and a monochrome
monitor to display debugging info. CodeView has none of the other
features above, though in some cases an expensive add-on product
provides them.
Optimizations.
Borland C++ gives you greater control over how the compiler optimizes
your program with 13 independent classes of code optimizations. You
can select the best combination of optimizations for your application,
trading off execution speed and program size. Microsoft has just as
many optimizations, but it is often not clear whether or not they
overlap one another until you have experimented with the various
choices.
Borland C++ provides in-line code generation for 19 frequently used C
functions, Microsoft C for an indeterminate number. An in-line
function often generates more code than a function call does, but it
executes much faster than library function calls, especially on 386
and 486 PCs with CPU cache memory.
Ansi Standard.
Borland C++ is fully compliant with the ANSI C specification and
incorporates the latest C++ 3.0 draft specification. Compiling with
Borland C++ gives you extensive warning diagnostics, many of which
tell you things about your program that even a commercial LINT program
will not. Using these diagnostics, you can spot a problem area and
change your program before debugging it, often avoiding long debugging
sessions.
Development Tools.
Borland C++ is a complete development environment that includes many
productivity tools which are not part of Microsoft C. If you ever want
to search a group of source files to find occurrences of the same or
similar strings of text such as variable or function names, the
Borland C++ UNIX-style GREP program will do the job.
Resource Workshop
For Windows development, the Resource Workshop is a single one-stop
utility that integrates into a coherent hierarchy all of the Windows
resources for a program, and allows you to conveniently edit, add, or
delete any Windows resource from your program. It even allows you to
edit the resources in an .EXE version of a program, a feature that is
extremely useful for creating national language versions and for doing
special customizations.
Turbo Profiler
The Turbo Profiler allows you to profile Windows and non-Windows
programs alike, and to isolate time-consuming hot spots in the code.
It measures the exact amount of time spent by your application on a
function-by-function basis, or for each single statement executed by
your program.
Other tools
The H2ASH utility generates assembly language structures from C or C++
header files, allowing you to easily keep C and assembly modules in
sync. The TOUCH utility updates the file system date for a file or a
set of files, so you can easily trigger an operation across a group of
files such as a file backup or a program make. The OBJXREF program
generates a cross-reference of global functions and variables used
within object files and libraries, so you can see at a glance the
relationship between function definitions and calls or among usages of
global variables.
Class Libraries.
The Object Windows Library (OWL) is a C++ class library containing the
classes used to program user interfaces for Windows applications.
Turbo Vision is a similar library for DOS-based applications. Finally,
the Borland C++ class libraries consist of reusable software to manage
many objects used every day by programmers: sorted arrays, btree
structures, linked lists, queues, hash tables, stacks, strings, and
the PC hardware timer. Borland C++ includes the source code for most
of these libraries, so that if you need to better understand how a
function works, or if you want to derive a similar function, you can
readily do so.
These are the many reasons why you should use Borland C++. As you use
it more, you will surely find some more reasons yourself.
Here is a summary to give you a quick start in getting your Microsoft
C program running with Borland C++.
1) Make sure your programs compile and run correctly with Microsoft C.
There is no need to confuse things by converting programs that do not
already work. If you do so, and something goes wrong, you won't know
whether there was a bug in the original program, or the problem arose
during the conversion process.
2) Start up the Borland C++ IDE (Integrated Development Environment) and
open a new project, giving it the same name as your compiled program.
3) Select Borland C++ Keywords in the Options|Compiler|Source menu item
of the IDE. This option tells the compiler to recognize the Borland
C++ extension keywords, including near, far, huge, asm, cdecl, pascal,
interrupt, _es, _export, _ds, _cs, _ss, and the register
pseudovariables.
4) Now, add to the project the names of all of the C source (.C) files
and .ASM modules for any assembly language functions you may have. If
you are writing a program for the Windows environment, add .RC and
.DEF files to the project as well. The Borland C++ IDE automatically
keeps track of the other dependencies involving .H header files, .BMP
bitmap files, .ICO icon files, .CUR cursor files, and assembly
language include files.
5) Turn on all warnings with the Options|Compiler|Messages menu item or
with the -w command line option.
6) Compile each module without any optimizations enabled.
7) Any compiler warnings generated by Borland C++ will alert you to
potential pitfalls. These catch many subtle programming errors
otherwise not found until you debug your program. Try to figure out
why the warning was generated. You might try to add ANSI function
prototypes and explicit typecasts whenever you are in doubt about the
correctness of the executable program.
8) If you have any C-callable functions written in assembly language,
refer to the brief discussion later on about C functions written in
assembly language.
9) Test your program, referring to the information and the sample
programs in the following sections. They explain and illustrate the
differences between Microsoft C and Borland C++ in detail.
10) Finally, when your program is fully operational, recompile it with the
required code optimizations enabled, and test again.
11) If you want to compile your program from the command line rather than
with the Borland C++ IDE, generate a Borland make file with the
PRJ2MAK utility.
This set of steps is not exhaustive and it does not cover every
possibility that might arise when converting Microsoft C programs, but
it is a reasonably complete set of guidelines for you to follow.
Compatibility
Borland C++ supports the same set of keywords as Microsoft C 5.1 with
the exception of fortran. Borland C++ also supports the same set of
keywords as Microsoft C 6.0 with the exception of:
-_based, _self, and _segname, because Borland C++ does not support
based pointers
- Borland C++'s keyword _seg is the equivalent of the Microsoft keyword
_segment
_emit; Borland C++ uses the pseudofunction _ _emit_ _, because this
style allows addresses of variables to be given as arguments, and
allows multiple bytes to be output; _emit, by contrast, works like an
assembly DB, allowing one immediate byte to be output. If your program
uses the Microsoft _emit, add the following statement to your program
after the including dos.h:
#define _emit(b) _ _emit_ _ (b)
_fortran; use the _pascal calling convention instead
Borland C++ provides _cs, _ds, _es, and _ss pointer types. See the
section "Mixed model programming: Addressing modifiers" in the Borland
C++ Programmers Guide for more information.
If your program uses the fortran calling convention for functions, you
can use the pascal calling convention instead. If you have many
fortran functions in a source module, you might find it convenient to
add the following statement just before all of the header declarations
in your source code module:
#define fortran _pascal
However, pay attention to the differences between Microsoft C and
Borland C++ in the scheme for passing floating point arguments,
especially if your fortran function is written in assembly language.
The __MSC macro
If your Microsoft C program uses the DOSERROR structure, then, and
only then, you need to add the definition of the _ _MSC macro to your
program to preserve compatibility with the Microsoft variable names
used within DOSERROR. In previous versions of Borland C++, you needed
to incorporate the _ _MSC macro to use many Microsoft C DOS and BIOS
functions. The statement
#define _ _MSC
needs to appear before the statement
#include <dos.h>
to use the Microsoft DOSERROR variable names.
The Header Files
You can use either the old Microsoft header file name or the
equivalent Borland C++ header file name according to the following
table:
Original Alias
alloc.h malloc.h
dir.h direct.h
mem.h memory.h
A Memory Model Overview
Although the same names are used for the six standard memory models,
there are some fairly significant differences in memory allocation for
the large data models in the standard memory configurations.
In Microsoft C, all large data models (compact, large, and huge) have a
default NEAR data segment to which DS is maintained. Data is allocated
in this data segment if the data size falls below a certain threshold,
or in a far data segment otherwise. You can set the threshold value with
the /Gtn option, where n is a byte value. The default threshold is
32,767. If /Gt is given but n is not specified, the default is 256.
In the other three memory models (tiny, small, and medium) under
Microsoft C, both a near and a far heap are maintained.
In Borland C++, the large and compact models but not the huge model have
a default NEAR data segment to which DS is maintained. All static data
is allocated to this segment by default, limiting the total static data
in the program to 64K, but making all external data references near.
In Microsoft's version of the huge memory model, a default data segment
for the entire program is maintained which limits total near data to
64K. No limit is imposed on array sizes since all extern arrays are
treated as huge (_huge).
In Borland C++'s huge memory model, each module has its own data
segment. The data segment is loaded on function entry. All data defined
in a module is referenced as near data and all extern data references
are far. The huge model is limited to 64K of near data in each module.
A command line compiler option, -Fs, and integrated environment dialog,
Options|Compiler, are available to allow the Borland C++ compiler to
assume that DS is equal to SS in all memory models. You can use it when
porting code originally written for Microsoft C that makes the stack
part of the data segment. When you specify this option, the compiler
will link in an alternate startup module (C0Fx.OBJ) that will place the
stack in the data segment. Usually the compiler assumes that SS is
equal to DS in the small, tiny and medium memory models (except for
DLLs).
The details of memory management functions, and the differences between
Microsoft C and Borland C++ in this area, are covered in the discussion
of MALLOC.H below and in the following section entitled "Converting
Microsoft DOS Memory Management Functions".
Constants and COMDEFs
Defining data in the header files in your program can cause duplicate
symbol errors at link time if the same header file is compiled into
multiple modules. Microsoft C generates communal variable (COMDEF)
records in the .OBJ files for global data allowing the linker to map
duplicate global data to the same storage location.
Borland C++ also supports COMDEF generation with the -Fc command-line
option. -Fc tells the compiler to generates COMDEFs for global "C"
variables that are not initialized and not declared as static or extern.
So long as a given variable doesn't need to be initialized to a nonzero
value, you don't need to include a definition for it in any of the
source files.
Some Conversion Hints
Use Portable Functions
Portable functions are those compatible with many different compilers
and machines. Generally they are ANSI standard functions. Whenever
possible, use only functions from the ANSI standard library (for
/example, use time instead of gettime). The portability boxes in the
Borland C++ Library Reference Manual will tell you if a function is ANSI
standard.
If you must use a function that's not in the ANSI standard library, use
a Unix-compatible function, if possible (for example, use chmod instead
of _chmod). Again, the portability boxes in the Borland C++ Library
Reference Manual will tell you if a function is available on Unix
machines.
Use Function Prototypes
Write function prototypes for all functions that do not yet have them.
Function prototyping was added to the ANSI C standard to help you find
subtle logic errors quickly. But you have to use function prototypes for
them to help you.
Avoid Machine Dependencies
Avoid the use of bit fields and code that depends on word size,
structure alignment or memory model. For example, Borland C++ defines
ints to be 16 bits wide, but a 32-bit C++ compiler would define 32-bit
wide ints.
Use ANSI standard manifest constants to refer to the various values and
arguments used by standard C functions. More generally, use manifest
constants to define constant values rather than sprinkling your program
with hard-coded "magic numbers".
DOSERROR
If you use the DOSERROR structure in a source module, insert the
preprocessor statement
#define _ _MSC
before dos.h is included.
/STACK Linker Option
If you were using the link option /STACK:n in your Microsoft C
application, initialize the global variable _stklen with the appropriate
stack size.
Source Program Conversion - Header by Header
Borland C++ provides far-reaching source language compatibility for DOS
and Windows programs written with Microsoft C Version 6.0a. The
exceptions consist of nonstandard functions and manifest constants that
are not often used. As a result, you should be able to compile almost
any Microsoft C6.0a source program with few source code changes, if any,
and have it working quickly with Borland C++.
The number of exceptions where you need to make source code changes are
listed below in alphabetical order arranged by Microsoft C header file
name, along with suggestions and examples for how to treat them. If a
Microsoft C header file is not listed here, this means that there are no
known issues with its compatibility between Microsoft C6.0a and Borland
C++. Eighteen of the 33 header files shipped with Microsoft C6.0a and
the Microsoft Windows Software Development Kit (SDK) are fully
compatible with Borland C++.
The functional areas of C that require the greatest number of changes
are memory management and graphics. If your Microsoft C6.0a programs
make extensive use of functions in these areas, refer to the more
lengthy sections that follow. They compare the Borland C++ and Microsoft
C approaches, contain programs that guide you through a successful
conversion, and compare functionally equivalent Microsoft C programs
side by side.
CTYPE.H
The manifest constants defined in the header files and used in the
various ctype functions are different between MSC6.0 and Borland C++. As
long as you use the portable ctype macros, this should present no issue.
If your program uses only the portable ctype macros, rather than
referring to the ctype manifest constants, it will behave the same with
either compiler.
If your program does refer directly to the Microsoft C ctype manifest
constants, add any of the following #defines as appropriate:
#define _UPPER _IS_UPP /* upper case letter */
#define _LOWER _IS_LOW /* lower case letter */
#define _DIGIT _IS_DIG /* digit[0-9] */
#define _SPACE _IS_SP /* tab, carriage return, newline, */
/* vertical tab or form feed */
#define _PUNCT _IS_PUN /* punctuation character */
#define _CONTROL _IS_CTL /* control character */
#define _HEX _IS_HEX /* hexadecimal digit */
Borland C++ has no equivalent for the _BLANK manifest constant used
within the Microsoft C version of the isprint macro. The following
program shows how to define and use a portable isblank macro to test for
a blank space. This is much better than using _BLANK.
/* ISBLANK.C illustrates use of the portable character classification
* function isblank.
*/
#include <ctype.h>
#include <stdio.h>
#define isblank(_c) isprint(_c) && !isgraph(_c)
void main()
{
int ch;
/* Display the blank character. */
for( ch = 0; ch < 256; ch++ )
{
if (isblank(ch))
printf ( "The value 0x%.2x is a blank space.\n", ch );
}
}
When compiled and run with either compiler, ISBLANK.C displays one line
of text, "The value 0x20 is a blank space."
The Microsoft C6.0a ctype header also contains two undocumented macros
useful primarily for the language syntax checking done by a C compiler:
iscsym and iscsymf.
DOS.H
If your Microsoft C6.0a program uses the dosexterror function and its
associated DOSERROR structure and variable names, add the following
statement to your program to define the DOSERROR structure according to
Microsoft C conventions:
#define __MSC
ERRNO.H
The numeric values of the manifest constants for many of the error codes
returned in the global variable errno differ between the Borland C++
errno.h and its Microsoft C6.0a counterpart. Many of these manifest
constants are present to provide compatibility with UNIX. As long as
your program refers to error codes using the manifest constants
themselves, rather than any numeric values, it will behave the same with
either compiler. The following pair of short code fragments illustrates
this point, and underscores the role of standard C manifest constants in
making programs portable:
/* ERRNO.H Example 1 - This example IS NOT portable */
int ThisError;
ThisError = errno;
if (ThisError == 7)
/* When reporting that an argument list that is too long,
the Microsoft C run-time library assigns value of 7
to the error code, while Borland C++3.0 run-time
library assigns a value of 20. */
printf("Arg list too long");
/* ERRNO.H Example 2 - This example IS portable */
int ThisError;
ThisError = errno;
if (ThisError == E2BIG)
/* When reporting that an argument list that is too long,
the manifest constant value E2BIG is returned by both
Microsoft C6.0a and Borland C++3.0. */
printf("Arg list too long");
FCNTL.H
The Borland C++ header file does not define the older UNIX manifest
constant O_RAW. If your Microsoft C program uses it, add the following
statement to your program after including fcntl.h:
#define O_RAW O_BINARY
FLOAT.H
Between Borland C++ and Microsoft C6.0a, there are very minor
differences in the values of some of the double precision (DBL_...) and
floating point (FLT_...) manifest constants that specify the limits of
computations. If your program explicitly references any of these
constants, make extra sure to verify that it produces the expected
results with Borland C++.
Also, some 8087/80287 status word subconditions (SW_...) and floating
point error signals (FPE_...) are defined as manifest constants in the
Microsoft C header, but not in the Borland C++ header. If your program
uses any of these manifest constants, add them to your program source
code with #defines.
GRAPH.H
The Borland C++ Borland Graphical Interface (GRAPHICS.H) is quite
different from the low-level graphics library supplied with Microsoft C,
although the respective functions show a general one-to-one
correspondence. If your programs currently use Microsoft's GRAPH.H, see
the following section entitled "Converting Microsoft DOS Graphics
Functions" for more details and examples.
LOCALE.H
The manifest constants LC_MIN and LC_MAX are not in the Borland C++
locale.h header file. If you use them in your Microsoft C6.0a program,
add the following prior to compiling with Borland C++:
#define LC_MIN LC_ALL
define LC_MAX LC_TIME
MALLOC.H
The Borland C++ memory management functions differ somewhat from the
memory management that is part of Microsoft C6.0a. If your programs
currently use Microsoft's MALLOC.H, see the section entitled "Converting
Microsoft DOS Memory Management Functions" for a comparison between the
two memory management facilities and some practical examples of
Microsoft C6.0a programs, before and after conversion to Borland C++.
If your programs rigorously use only the ANSI standard C memory
allocation functions, it is unlikely that you will have any difficulty
recompiling and running your programs with Borland C++. If you use the
DOS-specific memory management functions provided by Microsoft C, then
you will have to take some care in converting your programs.
MATH.H
Older versions of Microsoft C used a 6-byte floating point format that
predated the standard IEEE format. Microsoft C6.0a provides a set of
functions to convert data between Microsoft's old format and the IEEE
format. These functions are typically used for converting data files
from one format to the other. Borland C++ does not support the
proprietary Microsoft floating point format. Use the standard IEEE
format instead, and convert all of your data files to IEEE format.
Borland C++ does not provide the Bessel functions of the first and
second kinds which are available in the Microsoft C6.0a run-time
library: j0, j1, jn, y0, y1, yn, _j0l, _j1l, _jnl, _y0l, _y1l, and _ynl.
PGCHART.H
Borland C++ does not include functions to display presentation graphics,
a library added to Microsoft C with Version 6.0a.
PROCESS.H
The Microsoft 6.0a functions wait is not in the Borland C++ header file.
wait is a function available under UNIX.
SIGNAL.H
The Borland C++ header file does not define SIGUSR1, SIGUSR2, and
SIGUSR3, manifest constants for user signals contained in Microsoft
C6.0a. If your program uses them, you need to define them yourself prior
to compiling with Borland C++.
STDDEF.H
The Borland C++ header file does not define the errno variable, as does
Microsoft C6.0a. Instead the function prototype for errno is in
Borland's errno.h, so add the following to your program:
#include <errno.h>
The function prototype for errno is also compiled conditionally by the
dos.h and stdlib.h headers.
STDIO.H
If your program uses the high-level functions defined in this header
file, your Microsoft C6.0a programs will compile and run with no
changes. You need to be aware of a few things, however, if your program
accesses any of the low-level elements defined in the Microsoft stdio.h
header:
The Microsoft manifest constant, _NFILE, defines the maximum number of
files that your program can have open at one time. Replace all
references to _NFILE with references to the Borland C++ equivalent,
FOPEN_MAX. Better still, add the following statement to your program
after #include'ing stdio.h:
#define _NFILE FOPEN_MAX
If your program does the low-level stream I/O table manipulations
typically found in older K&R-style C programs, then all references to
the Microsoft C6.0a array, _iob[], need to refer instead to the Borland
C++ array, stream[]. The simplest solution is to add the following
statement to your program:
#define _iob stream
The Microsoft C high-level macros getc and putc use the undocumented
low-level _filbuf and _flsbuf functions, respectively. As long as your
programs use only high-level portable stream I/O functions, this is not
a problem.
STDLIB.H
If your program uses the function perror defined in the Microsoft C6.0a
version of stdlib.h, add the following statement which adds the function
prototype definition for the Borland C++ perror:
#include <stdio.h>
Note that the ANSI standard defines the perror function in STDIO.H and
not STDLIB.H.
If your program uses the proprietary Microsoft function, onexit, replace
all occurrences with the ANSI standard function, atexit. The easiest way
to do this is with a single statement that makes the substitution with
the C macro preprocessor:
#define onexit atexit
TIME.H
The manifest constants CLOCKS_PER_SEC and CLK_TCK have different values
for Microsoft C6.0a and Borland C++. If you use the defined macros then
no source code change is required. If your program depends on the
specific value, either redefine them with the Microsoft C values, or
change your program to use the Borland C++ values.
Assembly Language Functions Called by C Programs
The conventions for passing arguments to functions on the stack are
compatible between Borland C++ and Microsoft C6.0a for equivalent memory
models (tiny, small, medium, large, compact, huge), and equivalent
function types (near, far, cdecl, pascal, or _farcall). But there are
some differences in the handling of return values by the compilers and
these may require changes to your assembly language functions. These
details are important for assembly language functions, but somewhat
transparent for functions written in C. When your C function and your
calling program are written, the Microsoft C and Borland C++ compilers
adjust automatically for these differences in handling return values.
Structures Returned By Value
In a Microsoft C function declared with _cdecl, the function returns a
pointer to a static location. This static location is created on a
per-function basis. For a function declared with _pascal, the calling
program allocates space on the stack for the return value. The calling
program passes the address of the return value in a hidden argument to
the function.
Borland C++ returns 1-byte structures in AL, 2-byte structures in AX and
4-byte structures in AX and DX. For 3-byte structures and structures
larger than 4-bytes, the compiler passes a hidden argument (a far
pointer) to the function that tells the function where to return the
structure.
Integer Return Values.
Microsoft C and Borland C++ are compatible in their conventions for
returning simple integer variables. They return 1-byte variables (char)
in AL, 2-byte variables (int, short, and near) in AX and 4-byte
variables (long and far) in AX and DX.
Floating-Point Return Values.
In Microsoft C, _cdecl causes float and double values to be returned in
the _ _fac (floating point accumulator) global variable. Long doubles
are returned on the NDP stack. _fastcall causes floating point types to
be returned on the NDP stack. _pascal causes the calling program to
allocate space on the stack and pass an address to the function. The
function stores the return value and returns the address.
In Borland C++, floating point values are always returned on the NDP
stack.
Rules for EXTERNs and External Symbols
Borland C++ applies different rules than Microsoft C6.0a for generating
external symbols for the Turbo Linker, depending on whether the function
type is cdecl (default) or pascal. For cdecl functions, the rule is C
function_name --> _function_name, i.e. function name retains its case
and the underbar character is prefixed to it. For pascal functions, the
rule is C function_name --> FUNCTION_NAME, i.e. function name simply
transformed to upper case. In general, you would use pascal functions
only in Windows programs.
The following set of changes to your assembly language source code
should deal with many compatibility issues between Borland C++ and
Microsoft C: (See the Turbo Assembler User's Guide and Programmer's
Guide for more information.)
1. Add the following directives at the beginning of your program to tell
the Turbo Assembler (TASM) how to deal with Microsoft assembler (MASM)
compatibility:
ifdef ??Version ; defined only by TASM
MASM51 ; MASM 5.1 compatibility
QUIRKS ; assemble with MASM quirks
endif
2. If your functions written in assembly language use the MASM .MODEL
directive for standard segmentation, then your functions will take the
form: (The TASM MODEL directive is the equivalent of .MODEL.)
public _asm_func
_asm_func PROC FAR USES SI DI DS, ASMARG:WORD
Change this to:
public ASM_PROC
ASM_PROC PROC FAR USES SI DI DS, ASMARG:WORD
3. Similarly, if your assembly language functions use older style
segmentation, then your functions will take the form:
public _asm_func2
_asm_func2 PROC
<executable statements>
_asm_func2 ENDP
Change this to:
public ASM_FUNC2
ASM_FUNC2 PROC
<executable statements>
ASM_FUNC2 ENDP
4. Far more preferable to the approach in item 3 above, modify your
programs to use the TASM MODEL directive and the extended PROC syntax
shown in item 2 above. The benefit of the extended PROC is that the all
details of passing arguments and returning values are managed
automatically by TASM, and you need not concern yourself with them.
Converting Microsoft DOS Memory Management Functions
C programs written for the conventional MS-DOS environment rely on the
Intel segmented architecture to access data on the heap. The Intel
segmented architecture limits to 64K bytes the amount of data that can
be accessed with one setting of a segment register. It also forces an
arbitrary division between the near heap and the far heap.
The near heap is the heap space available in the default data segment
after static and stack data have been allocated. The far heap consists
of the remaining available conventional DOS memory after a program is
loaded and its code, data, stack, and near heap space are allocated.
Borland C++ and Microsoft C have slightly different but quite compatible
heap manager implementations to deal with the intricacies of segmented
architecture, but you need to convert Microsoft's non- standard heap
function calls to ANS or Borland C++ function calls.
Borland C++ memory management design and implementation are more robust
than Microsoft's. These are the advantages of Borland C++ memory
management:
When a Borland C++ program starts up, the Borland C++ memory management
functions treat all of the available conventional DOS memory as a single
free far heap block. When a Microsoft C6.0a program starts up, its heap
management run-time library normally allocates _amblksiz bytes of memory
as the initial free far heap space. The Microsoft global variable
_amblksiz has a default value of 8192 bytes. Subsequently, the
Microsoft C6.0a heap manager adds _amblksiz bytes of memory to the far
heap whenever it has allocated all of the free far heap space and needs
to get more from DOS. If your program uses the heap in an extremely
dynamic manner, you will find Borland C++ memory management faster.
Borland C++ does not allocate memory blocks on the heap when a program
requests a block size of zero bytes. This is treated as an error
condition, because a heap allocation of zero bytes is logically
inconsistent with good programming practice. Microsoft C allocates a
heap block of zero bytes without indicating an error.
Borland C++ satisfies any single request for more than 64K bytes of heap
space if your program is compiled with an appropriate memory model,
compact, large, or huge. All of the far heap management functions
support huge heap blocks, those that are greater than 64K bytes in size.
Only the Microsoft C6.0a halloc and hfree functions allocate huge heap
blocks.
When a program releases a memory block from the heap, the Borland C++
heap manager cleans up free heap space. It also links together any free
heap blocks that are consecutive in memory to form a single larger free
heap block. This allows Borland C++ to reuse free heap space when your
program makes a subsequent heap allocation request. With Microsoft C
heap management, the free heap space remains fragmented, and it
sometimes does not get reused. If your program, compiled under Microsoft
C6.0a, allocates and deallocates memory very frequently, there is a
reasonable probability that it will be unable to obtain a memory block
to satisfy a memory allocation request.
Borland C++ allows your program to determine the status of free memory
on a heap. However, it does not allow you to examine the contents of
free heap memory, which is really not owned by your program. Microsoft C
permits you to examine the contents of free heap directly. But neither
memory management scheme can prevent your program from overwriting free
heap memory if a pointer goes astray.
The Microsoft C functions that expand the heap do not move heap blocks
in memory. The Borland C++ realloc functions sometimes relocate heap
blocks in memory to increase the probability that a request to grow a
heap block will be successful. As a rule, you should always make sure
that any pointers aliased to heap blocks are updated after a realloc
function.
Microsoft C Based Heaps
The nonstandard based heap feature was introduced initially by Microsoft
with Version 6.0 of Microsoft C. Borland C++ does not support based
pointers, and it has no function prototypes (function names _b...) for
using the based heap. You would typically use based pointers in a large
or huge memory model Microsoft C program to give you a faster method to
accessing data than using the far heap. If your Microsoft C program uses
based heap functions, you can take one of two possible courses of
action:
1. Recompile your program with Microsoft C6.0a adding the following
statement at the beginning of your program:
#define _MSC_VER 510
This directive forces the Microsoft C compiler to generate warning or
fatal error messages for all references to based heap functions and the
related elements _based, _segment, _self, and _segname. Replace the
based heap functions with comparable far heap functions, change all
references to _based pointers, remove all definitions of based variable
types, and check out your program for correct operation. Finally,
recompile your program with Borland C++.
2. Compile your program with Borland C++, and replace all based heap
functions with borland far heap functions (farheap...), delete all
_segment variables, and change the references to _based pointers. Now,
check out your program for correct operation.
Two sample programs, BASE_BEF.C and BASE_AFT.C, show you how to deal
with the Microsoft C6.0a based variable functions and constructs.
BASE_BEF.C exercises the Microsoft based variable and based heap memory
management functions. BASE_AFT.C achieves the same end result by using
the Borland C++ farheap instead of the Microsoft based heap. These
programs are available for download (see the appendix for more details).
General Comparison of Heap Functions
The following sections contain a comparison of Microsoft C and Borland
C++ heap functions. Two sample programs MFARHEAP.C and BFARHEAP.C show
you how to convert from Microsoft C6.0a far heap calls to Borland C++
far heap calls. MFARHEAP.C exercises the Microsoft far heap memory
management functions prefixed by the _f symbols. BFARHEAP.C achieves the
same end result by using the Borland C++ farheap functions. These
programs are available for download (see the appendix for more details).
heapadd functions.
The Microsoft heapadd functions, _heapadd and _bheapadd, expand the size
of the appropriate heap by requesting additional memory from DOS and
adding it to the threaded list used to manage heap space. Note that all
of these functions are non-portable and non-standard. When a Microsoft
C6.0a program starts up, the heap management run-time library normally
allocates _amblksiz bytes of memory, but less than the total amount of
unused DOS conventional memory. The default value for _amblksiz is 8192.
Subsequently, the Microsoft C6.0a heap manager adds _amblksiz bytes of
memory to the far heap whenever it has run out of free heap space.
Borland C++ has no corresponding heapadd functions because it manages
free heap space differently. When a program compiled with Borland C++
starts up, the heap management run-time library allocates all of the
unused DOS conventional memory as free far heap.
Recommended Action: Remove heapadd function calls, or insert the
following #define which causes the C preprocessor to ignore all
occurrences of the function call:
#define _heapadd(a,b)
expand functions.
The Microsoft C6.0a expand functions, _expand, _bexpand, _fexpand, and
_nexpand, change the size of a previously allocated block of heap
memory. The size of a memory block may become either larger or smaller
as the result of a Microsoft C6.0a expand function. An expand function
does not move a block around in memory to make it larger. If an expand
function cannot increase the size of a heap block because the memory
above it is already allocated, it returns an error.
Borland C++ has no corresponding expand functions because it manages
free heap space dynamically, but the Borland C++ realloc functions,
realloc and farrealloc, perform a task similar to the expand functions.
These functions do relocate a heap block if required, so they are less
likely to fail to expand a heap block than the Microsoft C expand
functions.
Recommended Actions: Substitute realloc function calls for Microsoft
expand function calls, using realloc in place of either _expand or
_nexpand, and farrealloc in place of either _fexpand or _bexpand. Since
realloc returns a pointer to the memory block, which may have been
relocated, you will also have to make sure that you always use the new
pointer value when referring to data in the reallocated heap block. If
possible, use the ANSI standard realloc function in preference to the
DOS-specific farrealloc.
heapchk functions.
The Microsoft C6.0a heapchk functions, _heapchk, _bheapchk, _fheapchk,
_nheapchk, check the consistency of an entire heap. With Microsoft C6.0a
memory management, there are three possible error conditions: the heap
header control area is invalid, the heap area is uninitialized, or a
heap node contains invalid data.
Borland C++ provides the heapcheck and farheapcheck functions that
accomplish the same objective as the Microsoft heapchk functions. They
return only two error conditions: the heap area is uninitialized, and
the heap is corrupted.
Recommended Action: Substitute heapcheck function calls for Microsoft
_heapchk function calls, using heapcheck in place of either _heapchk or
_nheapchk, and farheapcheck in place of either _fheapchk or _bheapchk.
The sample programs MFARHEAP.C and BFARHEAP.C in the following section
entitled "Converting from Microsoft Heap Management to Borland C++ Heap
Management" show how this is done with a #define for _fheapchk.
heapmin functions.
The Microsoft C6.0a heapmin functions, _heapmin, _bheapmin, _fheapmin,
and _nheapmin, release unused heap memory to DOS.
Borland C++ has no corresponding heapmin functions because it manages
free heap space differently. See the discussion under heapadd Functions.
Recommended Action: Remove heapmin function calls or insert the
following #define which causes the C preprocessor to ignore all
occurrences of the function call:
#define _heapmin()
heapset functions.
The Microsoft C6.0a heapset functions, _heapset, _bheapset, _fheapset,
and _nheapset, check a heap for consistency and initialize all bytes of
free heap memory to a constant value. Your program can later verify that
the heap has not be overwritten by a stray pointer by checking all free
heap memory for the same constant value using a matching heapchk
function.
Borland C++ provides the heapfillfree and farheapfillfree functions that
accomplish the same objective as the Microsoft heapset functions. Both
the Microsoft heapset and Borland C++ heapfillfree functions return the
same error conditions as their corresponding heapchk functions.
Recommended Action: Substitute Borland C++ heapset function calls for
Microsoft _heapset function calls, using heapset in place of either
_heapset or _nheapset, and farheapset in place of either _fheapset or
_bheapset. The sample programs MFARHEAP.C and BFARHEAP.C show how this
is done with a #define for _fheapset.
heapwalk functions.
The Microsoft C6.0a heapwalk functions, _heapwalk, _bheapwalk,
_fheapwalk, and _nheapwalk, traverse the heap and return a heap
structure containing information about the next heap entry. Prior to
calling a heapwalk function, you initialize the heap structure with a
pointer value, either to a valid heap block, or NULL, if you want to get
information about the first block in the threaded heap list. The
Microsoft heapwalk functions return heap information about all heap
blocks of a given type, whether allocated or free. They return the size
of the heap block that was allocated, excluding control structures and
padding bytes.
Borland C++ provides the heapwalk and farheapwalk functions that
accomplish an objective similar to the Microsoft heapwalk functions.
However, the Borland C++ heapwalk functions return heap information only
about heap blocks that are currently allocated to your program. It also
returns the size of the heap block including control structures and
padding bytes.
Recommended Actions: Substitute heapwalk function calls for Microsoft
_heapwalk function calls, using heapwalk in place of either _heapwalk or
_nheapwalk, and farheapwalk in place of either _fheapwalk or _bheapwalk.
You may also have to change the logic of your program slightly to use
these functions which are primarily an adjunct to debugging. The sample
programs MFARHEAP.C and BFARHEAP.C show how this is done with a #define
for _fheapwalk.
msize functions.
The Microsoft C6.0a msize functions, _msize, _bmsize, _fmsize, and
_nmsize, return the size of a memory block allocated on the heap with a
given pointer. Borland C++ has no similar function.
Recommended Actions: Every time you allocate a memory block using one of
the malloc functions or change its size with a realloc function, you
will need to save and tabulate the number of bytes allocated, kept on a
one-to-one basis with the pointer to the allocated memory. Then, change
every reference to an msize function and its associated pointer argument
to use the number of bytes previously allocated for that pointer. DO NOT
use the Borland C++ heapwalk functions to find out the size of a memory
block on the heap, because these functions return a value that includes
the size of heap block control structure and any padding bytes. The
sample programs MFARHEAP.C and BFARHEAP.C show how this might be done.
Other Microsoft Based Heap Functions
Microsoft C6.0a has other functions that allocate, reallocate and
release memory from a based heap. These functions are _bcalloc, _bfree,
_bmalloc, and _brealloc. The _bheapseg and _bfreeseg functions allocate
and deallocate based heap segments, respectively. Borland C++ does not
support the based heap, based pointers, and _segment variables.
Recommended Actions: Remove all _bheapseg and _bfreeseg function calls,
and all definitions of variables of the type _segment. Change all _based
pointers to _far pointers. As a general rule when converting to Borland
C++, substitute either the corresponding ANSI standard memory allocation
function, or the corresponding Borland C++ far heap memory allocation
function. You should use ANSI standard functions whenever possible to
facilitate portability, as long as they permit you to manage memory as
you need to do. Because all of the Microsoft C6.0a based heap functions
take an additional segment variable as an argument, it is not
straightforward to write a set of #define's to make the substitution.
The sample programs BASE_BEF.C and BASE_AFT.C serve together as an
example to show you how to convert programs that used based heap
variables.
freect
The Microsoft _freect function inquires about the maximum number of
items can be allocated on the near heap, where an item is a fixed number
of bytes in size. _freect would typically be used in tiny, small or
medium memory model Microsoft C programs.
Borland C++ does not have a similar function, but it does have the
coreleft function that returns the total number of bytes of unused
memory at the top of the heap.
Recommended Actions: Substitute the coreleft function for _freect.
Compute the effective item size by adding six to the item size then
round it up to the nearest multiple of 16. Finally, compute the maximum
number of items that can be allocated by dividing the memory left by the
effective item size, and pass this argument to coreleft. The Borland
C++ heap management functions require a six byte control structure for
each heap block. They always allocate a heap block on a paragraph
boundary, demanding that the effective size allocated is an exact
multiple of 16.
Keeping Out of Heaps of Trouble
Here are some other tips to help you work effectively with the Borland
C++ heap manager.
The Microsoft C _nheap family of functions map directly into the ANSI
heap functions of Borland C++.
The Microsoft C _fheap family of functions map directly to the Borland
C++ farheap set of functions, as shown by the sample MFARHEAP.C and
BFARHEAP.C programs.
To have the greatest degree of portability and to guarantee defect- free
program, whenever you reallocate heap space, always make sure that you
use the current segment:offset value of a heap pointer returned by the
heap manager. And, especially, be sure that any pointers derived from
the pointer returned by the heap manager are all initialized to the
latest value before use.
Environments and tools
The Borland C++ IDE is roughly the equivalent of the Programmer's
Workbench, although naturally we think you'll find the IDE much easier
to use. Chapter 3 of the Borland C++ User's Guide manual provides a
complete reference to the IDE.
The IDE loads its settings from two files: TCCONFIG.TC, the default
configuration file, and a project file (.PRJ). TCCONFIG.TC contains
general environmental information. The current project file contains
information more specific to the application you're building.
A project is the IDE's equivalent of a makefile. It includes the list of
files to be built, as well as settings for the IDE options that control
the compilation and linkage of that program. If you don't specify a
project file when you start the IDE, a nameless project is opened and
set with default compiler and linker options, but no file name list.
Unlike Microsoft C, however, Borland C++ does not automatically create
and run a makefile based on settings and file names that you give it in
the project. If you want to use the IDE to set up a project, but use
MAKE to do the actual build, then you can use the PRJ2MAK utility to
convert a project file to a makefile.
The following sections describe the significant differences between
Borland C++'s MAKE, Project Manager, linker (TLINK), and command-line
compiler (BCC) and Microsoft C's NMAKE, LINK, and CL.
Paths for .h and .LIB files
Microsoft C requires two environment variables, LIB and INCLUDE. The
Microsoft C compiler uses INCLUDE to find standard header files.
Similarly, the Microsoft linker uses the LIB variable to discover the
location of the run-time libraries. Borland C++ does not use environment
variables to store the paths for the library and the include files.
Instead, you can easily set these paths in the IDE using the environment
options. If you are working with the command-line compiler or the
linker, you can use either command-line options or configuration files.
Remember that even if you haven't opened a project, Borland C++ will
store the paths in its default project file.
When you install Borland C++, you are asked to set paths for include
files and library files. Those paths become the default paths in the
IDE. The include and library files paths are also written to the default
command-line compiler configuration file TURBOC.CFG. The library path is
written to the default standalone linker configuration file TLINK.CFG.
In the IDE, you can change the default search paths for libraries and
header files with the Options|Directories command. The settings in the
Directories dialog box become a part of the current project.
For the command-line compiler, you can change the search path for
include and library files with the -I and -L options, respectively.
These options can also be changed in the configuration file for the
command-line compiler, TURBOC.CFG.
The linker can use the /L option to set search paths for libraries and
initialization code (like C0S.OBJ, the startup code for the small memory
model). For instance, this option
/LC:\BORLANDC\LIB;C:\WINAPPS\LIB
tells the linker to look in the two paths named for library and
initialization files.
You can also create a TLINK.CFG file. TLINK.CFG is a regular text file
that contains a list of valid TLINK options.
For the Windows Resource Compiler, the -x option tells it to ignore the
INCLUDE variable. In addition, you can specify an additional search path
with the -i option ( -i all by itself does not imply -x).")
When the Resource Compiler is invoked from the command line, it looks
for windows.h on the path specified by the INCLUDE environment variable,
if there is one. If that INCLUDE variable is set to some path other than
the location of the windows.h supplied by Borland C++, your module might
not be compiled correctly. (This does not occur in the IDE, because the
IDE passes the correct information to the Resource Compiler.)
For instance, if you have been using Microsoft C, then you probably have
an INCLUDE environment variable set to the path of the Microsoft C
header files. If you have also been using the Microsoft Windows SDK,
then the version of windows.h included with the SDK is probably also in
the INCLUDE directory.
When you're building a Borland C++ application, the Resource Compiler
should include the windows.h shipped with Borland C++. If you have a
defined INCLUDE environment variable, then you should tell the Resource
Compiler to ignore it with the -x option. (The same holds true for
Microsoft C LIB environment variable, i.e. it contains both the standard
C library path and the Windows library path, the latter only if you are
writing for Windows and you have installed the Windows library in a path
different than the standard MSC C libraries.)
MAKE
The version of MAKE supplied with Borland C++ 3.0 contains many new
features, some of which are designed to increase compatibility with
Microsoft's NMAKE. The new command-line switch -N turns on full NMAKE
compatibility. See Chapter 2 of the Borland C++ Tools & Utilities Guide
manual for more information on MAKE's options. The following list
summarizes the differences between MAKE and NMAKE.
NMAKE supports response files but MAKE doesn't.
In NMAKE, you must surround strings to be compared with quotes. MAKE
doesn't have this requirement; as long as the string to be compared
doesn't contain spaces, you can compare them without quotes.
NMAKE predefines several implicit rules; MAKE doesn't. However, the
BUILTINS.MAK file contains several implicit rules that you can use
without specifying them in the makefile.
MAKE doesn't pass through environment variables.
Command-line Compiler
The following table lists comparable BCC and CL command-line compiler
options. Some of the CPP (standalone preprocessor) options are listed.
In many multi-pass compilers, a separate pass performs the work of the
preprocessor, and the results of the pass can be examined. Since Borland
C++ uses an integrated single-pass compiler, we provide the standalone
utility CPP to supply the first-pass functionality found in other
compilers.
Note that most CL options that take arguments allow for a space between
the option and the argument. BCC options that take arguments are usually
immediately followed by the argument or list.
CL and BCC options compared
Microsoft C Borland C++
CL option BCC option What it does
N/A @name Gives the command-line
compiler a response
file name.
N/A +name Tell the command-line
compiler to use the
alternate configuration
file name
N/A -A ANSI keywords
N/A -A-, -AT Borland C++ keywords
(default)
N/A -AK Use only Kernighan and
Ritchie keywords.
N/A -AU Use only UNIX keywords.
/Zp2 -a Align word.
/Zp1 -a- Align byte (default).
/Aw, /Gw -WD Creates an .OBJ for Windows
to be linked as a .DLL with
all functions exportable.
/Aw, /GW -WDE Creates an .OBJ for Windows
to be linked as a .DLL with
explicit export functions.
/Ax -mx Use memory model x, where x
is t, s, m, c, l, or h.. For
BCC, following t, s, or m
with ! tells compiler to
assume DS != SS.
/Bn N/A Use alt preprocessor CnL.
N/A -B Compile and call the
assembler to process inline
assembly code.
N/A -b Make enums word-sized
(default)
N/A -b- Make enums signed
or unsigned.
/C N/A Preserve comments in C
preprocessor
N/A -C Nested comments on.
N/A -C- Nested comments off.(default)
/c -c Compile to .OBJ but do
not link.
/Did -Dname Define 'name' to the string
consisting of the null character.
/Did=value -Dname=string Defines 'name' to 'string'.
N/A -d Merge duplicate strings on.
N/A -d- Merge duplicate strings off
(default) (default).
N/A -Ename Use filename as the
assembler to use.
/E CPP -P Preprocess source to
standard output, include
line numbers.
/EP CPP -P- Preprocess source to
standard output, without
line numbers.
N/A -f- Don't do floating point.
N/A -ff Fast floating point (default).
N/A -ff- Strict ANSI floating point
N/A -ff- Strict ANSI floating point.
N/A -f87 Use 8087 h/w instructions.
N/A -f287 Use 80287 h/w instructions.
/F hexnum N/A Sets stack size to hexnum
bytes (hexnum must be
hexadecimal).
(By default) -Fc Generates COMDEFs.
N\A -Fm Enables the -Fc, -Ff, and
-Fs options.
(By default) -Fs Make DS==SS for all
memory models
/Fa [file] N/A Create assembly listing.
Name for list file defaults
to Source.ASM.
/Fb N/A Creates a bound executable file
/Fc [file] -S Produces a combined source
and assembly code listing.
Name for list file defaults
to Source.COD.
/Fe file -efile 'file' names executable file.
/Fl [file] N/A Creates object code list.
Name for list file defaults
to Source.COD.
/Fm [file] -M Creates map file. Name
defaults to Source.MAP,
where source is the first
source file specified.
/Fo file -ofile 'file' names object file.
/FPa N/A Generate floating-point
calls; select alternate math
library.
/FPc -f Emulate floating point
(default, coprocessor used if
present at run time).
/FPc87 N/A Selects 80x87 library (80x87
coprocessor must be present
at run time).
/FPi N/A Inlines 80x87 instructions;
selects emulator library
(coprocessor used if present
at run time).
/FPi87 -f87, -f287 Inlines 80x87 instructions;
chooses coprocessor library
(coprocessor must be present
at run time).
/F[file] N/A Generates standard PWB
Source Browser database.
/FR[file] N/A Generates extended PWB
Source Browser database.
/Fs [file] N/A Produce source list file.
defaults to Source.LST.
/Fx [file] N/A 'file' specifies a name
for the MASM cross-reference
file.
G0 -1- Generate 8088/8086
instructions.
G1 -1 Generate 80186 instructions.
G2 -2 Generate 80286
protected-mode compatible
instructions.
/Gc -p Use Pascal calling
convention. For CL, this is
Pascal or FORTRAN, but they
currently same calling
convention.
/Gd -p- Standard C calling
conventions (default).
/Ge -N Check for stack overflow.
(Default for CL, but not for
BCC).
/Gi N/A Compile incrementally (for
use with quick compile
option /qc).
/Gm N/A Store strings in CONST seg
N/A -gn Stop compilation after n
warning messages
/Gr -pr Enables _fastcall to call
conventions for functions
(if possible, passing value
in registers).
/Gs -N- Turn off checking for stack
overflow. (Off by default
for BCC.)
/Gt [number] -Ff[=size] Creates far variables
automatically; 'size' or
'number' is threshold.
/Gw -W Creates correct
prolog/epilog for Windows
program. For Borland C++,
this creates an application
with all functions exportable
/GW -WE Generates prolog/epilog for
explicit functions (marked
with _export) in Windows
program.
N/A -H Causes the compiler to
generate and use pre-
compiled headers.
N/A -H- Turns off generation and
use of precompiled headers
(default).
N/A -Hu Tells the compiler to use
but not generate precompiled
headers.
N/A -H=filename Sets the name of the file
for precompiled headers.
(By default) -h Use fast huge ptr math
/H number -inumber Restricts length of external
names to 'number'.
/HELP BCC Calls QuickHelp. For help on
BCC, simply invoke without
options.
N/A -in Make significant identifier
length to be 'n'.
/I dir -Ipath Directories for include files
For CL, adds directory to the
beginning of include file
search directory list.
N/A -jn Stop after 'n' compiler error
messages.
/J -K Changes default for char.
from signed to unsigned. For
Borland C++, -K- returns to
signed.
N/A -Jg Definitions for all template
instances, and merge
duplicates (default)
N/A -Jgd Public definitions for all
template instances
N/A -Jgx External references for all
template instances
N/A -k Std stack frame on (default).
N/A -Lpath Directories for libraries.
/Lc,/Lr /Td Tells linker to create a
real mode executable.
/Li [number] N/A Use incremental linker,
instead of standard linker.
Number specifies byte
boundary for padding near
functions.
/Lr See /Lc.
/link opts -lopts Pass 'opts' to linker when
invoked.
N/A -l-option Suppress 'option' for the linker
N/A -M Instruct the linker to
create a map file.
/MA option -Toption Pass 'option' to assembler
when invoked.
N/A -npath Set the output directory
/NDdataseg -zRname Sets the data segment name.
For BCC, option changes the
name of the uninitialized
data segment class to name.
By default, the uninitialized
data segments are assigned
to class BSS.
/NMmodule N/A Sets module name to 'module'
/nologo N/A Don't print sign-on banner.
/NTsegname -zCname Sets code segment name. This
option changes the name of
the code segment to 'name'. By
default, the code segment is
named _TEXT, except for the
medium, large and huge
models, where the name is
filename_TEXT. (filename
here is the source file name.)
N/A -O Optimize jumps.
N/A -O- No optimization (default).
/O [options] (See comment) Provides optimization. For
Borland C++, see specific
options; for instance, -Z,
-O, or -G.
/Os -G- Optimize for size (default)
/Os -O1 Optimize, smallest code
/Ot -G Optimize for speed
/Ot -O2 Optimize, fastest code
/Oa -Oa Optimize, no pointer aliasing
/Ow N/A no aliasing in function calls
N/A -Ob Optimize, dead store
elimination
/Og -Oc Optimize, local common
subexpression elimination
/Od -Od Optimize, disable all
optimizations
/Oe -Oe Optimize, global register
allocation, variable live range
/Og -Og Optimize, global common
subexpression elimination
/Oi -Oi Optimize, intrinsic functions,
automatic inlining
/Ol -Ol Optimize, loop optimization
/Ol -Om Optimize, loop invariants,
code motion on
/On N/A disable "unsafe" optimizations
N/A -Op Optimize, copy propagation
/Op N/A enable precision optimizations
/Or N/A disable inline return
/Os -Os Optimize, size of code
/Ot -Ot Optimize, speed of .EXE
/Ol -Ov Optimize, loop induction
variable, strength reduction
/Ox -Ox Optimize, speed: compatible
with Microsoft compilers
N/A -P Perform a C++ compile
regardless of source file
extension.
N/A -Pext Perform a C++ compile and
set the default extension to
ext.
N/A -P- Perform a C++ or C compile
depending on source file
extension (default).
N/A -P-ext Perform a C++ or C compile
depending on extension; set
default extension to ext.
N/A -p- Use C calling convention
(default).
/P CPP -P- -oname Preprocesses source file and
sends output to name
(CPP), or to Source.I (CL).
N/A -Qe Instructs the compiler to
use all available EMS memory
(default).
N/A -Qe- Instructs the compiler to
not use any EMS memory.
N/A -Qx Instructs the compiler to
use all available extended
memory.
N/A -Qx=nnnn Instructs the compiler to
reserve nnnn Kb of extended
memory for other programs,
and to use the rest itself.
N/A -Qx=nnnn,yyyy Instructs the compiler to
reserve 'nnnn' Kb of extended
memory for other programs
and 'yyyy' for itself.
N/A -Qx=,yyyy Instructs the compiler to
reserve 'yyyy' Kb of extended
memory for itself.
N/A -Qx- Instructs the compiler to
not use any extended memory
/qc N/A Invokes quick compile.
N/A -R Generate ObjectBrowser
information.
N/A -r Use register variables on
(default).
N/A -r- Suppresses the use of
register variables.
N/A -rd Only allow declared
register variables to
be kept in registers.
N/A -S Produce .ASM file
/Sx option N/A Set options for source
listing. Where 'x' is l, p,
s, or t.
N/A -T- Remove all previous
assembler options.
/Ta asm_src N/A Specifies that 'asm_src' be
treated as an assembler
source file.
/Tc srcfile N/A Specifies that 'srcfile' be
treated as a c source file.
N/A -tDe Compiled and linked program
is DOS .EXE file
N/A -tDc Compiled and linked program
is DOS .COM file
N/A -tW Compiled and linked program
is a Windows module using
the -W options
N/A -u Generate underscores (default)
N/A -u- Disable underscores
/u N/A Undefines all predefined
identifiers
/U Ident -UIdent Undefine any previous
definitions of 'Ident'.
N/A -V Smart C++ virtual tables.
N/A -Va Pass class args by reference
to temp variable
N/A -Vb Backwards compatibility,
virtual base class pointer
N/A -Vc Backwards compatibility,
no hidden members and code
N/A -Vf C++ far virtual tables
N/A -Vmv Member pointers have no
restrictions
N/A -Vmm Member pointers support
multiple inheritance
N/A -Vms Member pointers support
single inheritance
N/A -Vmd Use smallest representation
for member pointers
N/A -Vmp Honor declared precision for
all member pointer types
N/A -Vo Backwards compatibility,
master switch turns on all
N/A -Vp Backwards compatibility,
pass 'this' to pascal
member functions
N/A -Vt Place virtual table pointer
after non-static data members
N/A -Vs Local C++ virtual tables.
N/A -Vv Backwards compatibility,
don't change layout of classes
N/A -VmX C++ member pointers
N/A -V0, -V1 External and Public C++
virtual tables.
N/A -Vf Far C++ virtual tables.
N/A -v Source debugging on
N/A -v- Source debugging off
N/A -vi, -vi- Controls expansion of inline
functions.
/V string N/A Copies 'string' to object file
(for version control).
N/A -w Display warnings on.
N/A -wxxx Enable 'xxx' warning message.
N/A -w-xxx Disable 'xxx' warning message.
/w -w- Display warnings off.
N/A -WS Creates an .OBJ for Windows
that uses smart callbacks.
/W n (See -w) Set warning level 0, 1, 2,
3, or 4.
/WX -g1 Makes all warnings fatal. No
object files are generated
if warning occurs. (The -g
option takes the form -gn,
where n is the limit to
number of warnings.)
N/A -X Disable compiler
autodependency output.
/X N/A Ignore INCLUDE
environment variable list
of include search paths.
N/A -Y Enable overlay code
generation.
N/A -Yo Overlay the compiled files.
N/A -y Include line numbers in
.OBJ for debugger
N/A -y- Do not include line numbers
in .OBJ for debugger
N/A -Z Enable register usage
optimization.
N/A -zAname set Code class to 'name'
N/A -zBname set BSS class to 'name'
N/A -zDname set BSS segment to 'name'
N/A -zEname set Far segment to 'name'
N/A -zFname set Far class to 'name'
N/A -zGname set BSS group to 'name'
N/A -zHname set Far group to 'name'
N/A -zPname set Code group to 'name'
N/A -zSname set Data group to 'name'
N/A -zTname set Data class to 'name'
N/A -zX* Use default segment, class,
or group name for X.
/Za -A Enforces ANSI compatibility.
Use only ANSI keywords. No
vendor-specific extension
allowed.
/Zc N/A Ignores case for functions
declared as _pascal.
/Zd /y Generates line numbers for
symbolic debugger.
/Ze -A-, -AT Enable vendor-specific
extensions.
/Zg N/A Generates function
prototypes; writes to
standard output.
/Zi /v For Microsoft, generates
debugger information for
CodeView. For Borland C++,
generates information for
IDE debugger and Turbo
Debugger.
/Zl N/A Library search records not
written to object file.
/Zpn -a, -a- Packs structure members
on the 'n' byte boundary.
'n' can be 1, 2, or 4.
/Zr N/A Generates checks for null
pointers and far pointers
that are out of range.
/Zs files N/A Syntax check only.
Command-line Options and Libraries
The C0Fx.OBJ modules are provided for compatibility with source
files intended for compilers from other vendors. The C0Fx.OBJ
modules substitute for the C0x.OBJ modules; they are to be linked
with DOS applications only, not Windows applications or DLLs.
These initialization modules are written to alter the memory
model such that the stack segment is inside the data segment. The
appropriate C0Fx.OBJ module will be used automatically if you use
either the -Fs or the -Fm command-line compiler option.
The -Fc (generate COMDEFs), -Ff (create far variables), -Fs
(assume DS == SS in all models), and -Fm (enable all -Fx options)
command-line compiler options are provided for Microsoft
compatibility. These options are documented in full in Chapter 5
of the Borland C++ User's Guide manual.
Linker
The Borland C++ linker, TLINK, is invoked automatically from the
command- line compiler unless the -c compiler option is used.
Options such as memory model and target (Windows or DOS), are
passed from the compiler to TLINK; TLINK links the appropriate
libraries based on the compile options.
TLINK can be used to build both DOS and Windows programs. See
Chapter 4 in the Borland C++ Tools & Utilities Guide manual for
material on module definition file statements.
The following table compares TLINK and LINK options. Note that
Borland C++ TLINK options are case-sensitive, while Microsoft
LINK options are not.
LINK and TLINK options compared
Microsoft C Borland C++
Link option TLINK option What it does
N/A /3 Enable 32-bit processing.
/A:size /A=nnnn Specify segment alignment
for Windows images.
/BA N/A BATCH. Suppresses prompts
for library or object files
not found.
N/A /C Treat EXPORTS and
IMPORTS section of module
definition file as case
sensitive.
/CO /v Include full symbolic debug
information.
/CP:bytes N/A Sets the program's maximum
memory allocation to 'bytes'.
N/A /d Warn if duplicate symbols in
libraries.
/DOSSEG (See comment) For assembly programs,
forces a certain ordering of
segments in executable. To
enable DOSSEG for an
assembly program, include
DOSSEG in the source code.
/DS N/A For assembly programs, tells
linker to load data starting
at high end of DS instead of
low end.
/E N/A Packs the executable by
removing repeated series of
bytes.
/F By default For LINK, tells linker to
optimize far calls to
procedures in same segment
as caller. (Used with MS
/PACKCODE option.) For
TLINK optimizes far calls
automatically.
/HE /? Provides help on
command-line options.
/HI N/A For real-mode assembly
programs, places executable
as high in memory as possible.
N/A /i Initialize all segments.
/INC N/A Prepares for ILINK.
/INF N/A Tells LINK to display link
information while in process.
N/A /Lpaths Specify library search paths.
/LI /l Include source line numbers
and associated addresses in
map file.
/M /m Create map file with public
global symbols.
/NOD [:name] /n Don't use default libraries.
/NOE /e Ignore Extended Dictionary.
/NOF N/A Turns off far call
translation (see /F option)
/NOI /c Treat case as significant
in symbols.
/NOL N/A Suppress banner
/NON N/A Arrange segments in
executable in the same
order as they are arranged
by /DOSSEG.
/NOP /P- Turn off code packing.
N/A /o Overlay following modules or
libraries. Microsoft LINK
uses parentheses around
files to be overlaid. (Note
that the overlay scheme is
different between products.)
/O:number N/A Set interrupt 'number' for
passing control to overlays
(other than the default 63).
/PACKC[:n] /P=n Pack code segments. 'n'
specifies maximum size
of groups formed by
/PACKC or /P.
/PACKD[:n] N/A Pack data segments. 'n'
specifies maximum size of
groups formed by /PACKD.
/PADC:size N/A Tells LINK to pad code
module for ILINK by
'size' bytes.
/PADD:size N/A Tells LINK to pad data
segments by 'size' bytes.
/PAU N/A Pauses linking.
/PM:type N/A Sets window type for
Presentation Manager.
/Q N/A Produces Quick library.
N/A /s Create detailed map of
segments.
/SE:number N/A Sets maximum number of
segments allowed.
/ST:number N/A Sets stack size.
/T /t Produce .COM files.
N/A /Td Create target DOS
executable.
N/A /Tdc Create target DOS .COM file.
N/A /Tde Create target DOS .EXE file.
N/A /Tw Create target Windows
executable (.DLL or .EXE).
N/A /Twe Create target Windows
application (.EXE).
N/A /Twd Create target Windows DLL
(.DLL).
/W N/A Warn fixups.
N/A /x Don't create map file.
N/A /ye Use expanded memory for
swapping.
N/A /yx Use extended memory for
swapping.
Converting Microsoft DOS Graphics Functions
The differences between the Microsoft C6.0a DOS graphics system
and the Borland Graphics Interface are summarized for your
reference below.
Two sample programs, MSCGRF.C and BGIGRF.C, provide you with a
comparison between Microsoft C6.0a and Borland C++ graphics. You
will find them helpful as a reference as you convert Microsoft C
graphics programs to run with the Borland C++ BGI. These programs
are available for download (see the appendix for more details).
Supported Graphics Adapters
Microsoft C6.0a is a closed-ended graphics system that supports a
limited set of graphics cards. There is no public specification
from Microsoft explaining how to add support for other graphics
drivers. Graphics adapters recognized automatically by Microsoft
C6.0a graphics are Video Graphics Array (VGA), Extended Graphics
Adapter (EGA), Color Graphics Adapter (CGA), Multicolor Graphics
Array (MCGA), and the Olivetti/AT&T variations of the first three
standards.
In addition, if you run the Microsoft-supplied
terminate-and-stay-resident (TSR) program, MSHERC, Microsoft's
graphics recognizes and supports video adapters compatible with
the Hercules monochrome graphics hardware specification. If you
develop software for use by others, you must require your users
to run MSHERC before running your Microsoft C graphics programs
with a Hercules monochrome graphics adapter. MSHERC occupies
nearly 7K bytes of memory, and cannot be removed from memory once
installed.
The Microsoft C _getvideoconfig function returns information
about the current graphics adapter, and the _setvideomode
function sets up the adapter in an appropriate graphics mode.
The Borland Graphics Interface (BGI) is an open-ended graphics
system that supports industry standard graphics adapters.
Available from Borland is a specification that describes the BGI
and how to develop third-party BGI graphics drivers. The BGI
automatically recognizes and supports VGA, EGA, CGA, IBM PC 3270,
Olivetti/AT&T CGA, and Hercules monochrome graphics adapters. If
an IBM 8514 Application Interface (AI) TSR is installed on a PC
with an IBM 8514 or compatible graphics adapter, the BGI
recognizes and supports this device, in conformance with IBM's
recommendations for 8514 programming.
In addition to the BGI graphics drivers supplied with Borland C++
3.0, third-party BGI drivers have been developed to support
various VGA chip sets operating in Super VGA graphics modes that
offer higher resolution and/or more colors than standard VGA. The
Borland CompuServe Forum always contains information about
currently available BGI drivers.
With Borland C++, the initgraph function loads a graphics driver
from disk and puts the graphics system into graphics mode. It is
generally the first BGI function that your program calls. You may
also use the detectgraph function to override the graphics mode
selected by initgraph.
If you or users of your software have a third-party BGI graphics
driver available, your program would first use the
registerbgidriver function to register it for use by BGI, and
then call initgraph.
Make sure that your program can access the BGI drivers that it
needs to use. The third argument to the initgraph function gives
the path where your program finds all of the BGI drivers it can
use. Relying on just the initgraph function is the simplest for
you to program, but it may complicate the installation of your
software.
You may also add BGI drivers to the GRAPHICS.LIB library supplied
with Borland C++, link them into your program, then register them
for use by your program with the registerbgidriver function.
These steps simplify installation of your software, but add to
the amount of memory required by your program. See the on-line
help in the IDE and the documentation file UTIL.DOC for more
information about this treatment of BGI drivers.
Displaying Fonts
Microsoft C6.0a provides two types of graphics fonts, fixed
height bitmapped fonts and scalable vector fonts. It also has
special functions to display the built-in video BIOS bitmapped
font for the current graphics mode. Microsoft graphics manages
the BIOS font differently than the graphics fonts.
The Microsoft bitmapped fonts are in three typeface families:
fixed width Courier, sans serif proportional Helv, and serif
proportional Times Roman. The scalable vector fonts are Modern, a
narrow sans serif proportional font; Script, a handwriting-like
font; and Roman, a Times Roman look-alike.
The Microsoft bitmapped fonts cannot be resized. If you want to
use a specific bitmapped font, it is best if your program builds
a table of available fonts and their characteristics obtained by
calls to the _getfontinfo function. Then it can build a text
string describing the exact attributes of the required font, and
select the font with the _setfont function.
The Microsoft scalable fonts can be displayed at any size. In
addition, you can display a scalable font at any horizontal to
vertical ratio.
The Microsoft C6.0a graphics library does not have any functions
to justify text at the left, center, right, top, middle, or
bottom of a rectangular area. As a consequence, your program must
manage each step of the process: calculation of text width and
height, status of justification attributes, computation of
starting x-y text coordinate including justification, and,
finally, the actual display of the text.
To use Microsoft graphics fonts, your program must read them from
the directory passed to the _registerfonts function.
Borland C++ includes eleven vector fonts of the sans serif,
serif, and ornamental varieties. The default font is an 8x8
pixel sans serif font that can be resized in integral multiples
of 8 pixels using the settextsize function. You can resize all of
the other fonts to various sizes by using the settextsize
function. You can establish the horizontal-vertical ratio for
displaying text with the setusercharsize function. The default
horizontal-vertical ratio is one-to-one (1:1).
The Borland C++ settextjustify function sets up the rules used to
justify text. Once set up, text justification is done
automatically by the outtextxy function with respect to the
current graphics position.
To use Borland C++ graphics fonts, your program must read them
from the same directory in which the BGI drivers are found.
Alternately, you can link BGI fonts into your program,
registering and using them much like any BGI drivers you may have
linked into your program. You can register a font for use by your
program with the registerbgifont function. See the on-line help
in the IDE and the documentation file UTIL.DOC for more
information about treating BGI fonts in this fashion.
Finally, the Borland C++ 8x8 default font displayed at a 1:1
horizontal- vertical ratio offers the best fit for replacing the
built-in BIOS bitmapped font displayed by the Microsoft C6.0a
functions _outmem and _outtext. Note though that the sizes of the
BIOS fonts vary: CGA is 8x8, EGA is 8x14, Hercules is 9x14, and
VGA is 8x16.
The State of the Graphics System
Microsoft C6.0a does not have a complete set of function calls to
determine the current state of the graphics system. As a result,
you must keep track of the graphics system state yourself in your
programs, saving old and new state of each graphics attribute
when you set it. However, the following graphics state
information is maintained by Microsoft C graphics: x-y
coordinates, foreground color, background color, fill pattern,
line pattern, font characteristics, font orientation, and line
drawing mode.
Borland C++ has a complete set of function calls to return the
current state of each attribute in the graphics system. These
include graphics mode, palette, x-y coordinates, foreground
color, background color, palette, aspect ratio, fill pattern and
color, line pattern and color, font characteristics, font
orientation, and viewport settings.
Graphics Coordinate Systems
Microsoft C graphics have three types of functions for displaying
graphic objects: physical coordinates, viewport coordinates, and
two types of windowed coordinates. Physical coordinates serve
only as absolute physical reference points for graphics
operations; they are not used by any graphics functions that draw
on the screen.
Microsoft viewport coordinates are integer x-y values plotted
with respect to the zero point of the current window, as set with
the _setviewport function. The _outgtext function displays text
using the current viewport coordinates.
Microsoft windowed coordinates are floating point x-y values set
up with the _setwindow function, and may be positive or negative
numbers. Both _setviewport and _setwindow establish the
rectangular boundaries of a window using the upper left and lower
right corners of the rectangle. If you use windowed coordinates
for drawing graphic objects, you must also transform these
coordinates into viewport coordinates to display text with your
graph. Use either _getviewcoord_wxy or _getviewcoord_w to do
this.
The shape drawing functions draw lines, rectangles, arcs, and
polygons, get images from the screen, and put images onto the
screen. Each function that uses viewpoint coordinates has one or
two analogous functions in the windowed coordinate system. For
example, _arc draws an arc with viewport coordinates, while
_arc_wxy draw an arc in windowed coordinates. The _ellipse
function draws an ellipse using viewport coordinates, and both
_ellipse_w and _ellipse_wxy use windowed coordinates. The
windowed functions with the suffix _w accept coordinate arguments
with four distinct x-y values, while those with the suffix _wxy
take structures of x-y coordinate pairs as arguments.
Microsoft C graphics provides the _getphyscoord, _getviewcoord,
_getviewcoord_w, _getviewcoord_wxy, and _getwindowcoord functions
to map from one coordinate system to another, which is required
uses windowed graphics functions.
Borland C++ offers a unified view of graphics with a single set
of functions that all use viewport coordinates as a single frame
of reference. After the viewport is set, all functions operate
relative to the zero x-y coordinate of the viewport.
Other Things You Must Do Differently
Microsoft C 6.0a graphics has no predefined bitmap patterns for
filling shapes or drawing lines. You must design and describe
bitmap patterns in your program before using them. Microsoft C
graphics also does not have any parameter to control the width of
lines drawn. In the Microsoft graphics system, if you need to
draw a line more than one pixel wide, you accomplish this by
drawing several lines one pixel apart from each other until the
resulting line is wide enough.
Borland C++ allows you to use its built-in bitmap patterns to
fill shapes and to draw lines, and to define and use your own.
You can also vary the widths of lines drawn by the arc,
rectangle, pie, drawpoly, line, and linerel, or ellipse
functions.
Microsoft C6.0a graphics employs the concept of a bounding
rectangle, a rectangle drawn so that it contains a drawn ellipse,
or the ellipse from which a drawn shape is derived. A bounding
rectangle touches an ellipse or circle at exactly four points,
the vertices of the figure. For an arc or pie, the endpoints of
the drawn shape are marked by lines that intersect the bounding
rectangle. To draw a curved shape, you need to compute the upper
left and lower right of corners of its bounding rectangle from
its center point and radii.
The Borland C++ graphics system uses a simple and intuitive
system for drawing curved shapes. You need only to describe the
center point of the shape in x-y coordinates, and the radii. To
draw either an arc or pie shape, you also need to specify the
starting and ending angles of the endpoints, stated in degrees.
The Microsoft C graphics function _setwritemode controls the
logical line drawing mode used for _putimage, _lineto, _polygon,
and _rectangle operations. The manifest constants _GAND, _GOR,
_GPRESET, _GPSET, and _GXOR provide different ways to combine the
result of from the current drawing operation with the data
already on screen. The results are less than intuitive, as shown
by the pair of graphic programs BGIGRF.C and MSCGRF.C. Borland
C++ uses logical operators to control only the putimage function.
A Graphics Reference for Microsoft C Users
Here is a reference of graphics functions to help you convert
your Microsoft C graphics programs. BGI contains many other
useful graphics functions. This reference tabulates the BGI
functions that most closely correspond to Microsoft C graphics
functions. They are listed in alphabetic order by category of
graphics function.
Graphics System Control
Microsoft C Borland BGI
_getactivepage N/A, maintain in your program
_getvideoconfig detectgraph, initgraph,
getaspectratio,getpalette,
getmaxx, getmaxy
_getvisualpage N/A, maintain in your program
_setactivepage setactivepage
_setvideomode setgraphmode
_setvideomoderows No equivalent, uses BIOS font
_setvisualpage setvisualpage
Drawing & Filling
Microsoft C Borland BGI
_arc arc
_ellipse ellipse or fillellipse
_floodfill floodfill
_getarcinfo getarccoords [arc only]
_getcurrentposition getx & gety
_getcurrentposition_w No equivalent, remap to viewport
coordinates and use getx and gety
_getfillmask getfillpattern
_getlinestyle getlinesettings [line style,
pattern, & thickness]
_getwritemode N/A
_lineto lineto
_moveto moveto
_pie pieslice
_polygon drawpoly or fillpoly
_rectangle rectangle
_setfillmask setfillpattern
_setlinestyle setlinestyle [line style,
pattern, & thickness]
_setwritemode raster operations (ROPS) are
used as arguments to putimage
Text Output
Microsoft C Borland BGI
_displaycursor No equivalent, used in text mode
_getfontinfo gettextsettings
_getgtextextent textwidth
_getgtextvector No equivalent, maintain this
information in your program
_gettextcolor No equivalent, uses BIOS font
_gettextcursor No equivalent, used in text mode
_gettextposition No equivalent, uses BIOS font
_gettextwindow No equivalent, uses BIOS font
_outgtext outtext
_outmem No equivalent, uses BIOS font
_outtext No equivalent, uses BIOS font
_registerfonts registerbgifont
_scrolltextwindow No equivalent, uses BIOS font
_setfont settextstyle & setusercharsize
_setgtextvector settextstyle
_settextcolor No equivalent, uses BIOS font
_settextcursor No equivalent, used in text mode
_settextposition No equivalent, uses BIOS font
_settextrows No equivalent, uses BIOS font
_settextwindow No equivalent, uses BIOS font
_unregisterfonts No equivalent
_wrapon No equivalent, controls word wrap for
_outtext]
Screen, Viewport & Window
Microsoft C Borland BGI
_clearscreen cleardevice or clearviewport
_getimage getimage
_getphyscoord No equivalent,
view(x,y) --> physical (x,y)
_getpixel getpixel
_getviewcoord No equivalent,
physical (x,y) --> view(x,y)
_getviewcoord_w No equivalent,
window (wx,wy) --> view(x,y)
_getviewcoord_wxy No equivalent,
window (wx,wy) --> view(x,y)
_getwindowcoord No equivalent,
view(x,y) --> window(wx,wy)
_imagesize imagesize
_putimage putimage
_setcliprgn setviewport [also viewport]
_setpixel setpixel
_setvieworg setviewport [window & clip, too]
_setviewport setviewport [also clip]
_setwindow Window coordinates are
not available
Color Control
Microsoft C Borland BGI
_getbkcolor getbkcolor
_getcolor getcolor
_remappalette setpalette
_remapallpalette setallpalette
_selectpalette [Not available, CGA only]
_setbkcolor setbkcolor
_setcolor setcolor
State Query & Error Handling
Microsoft C Borland BGI
_grstatus graphresult & grapherrormsg